package object2D;

import byggeTegner.ByggeTegner;
import byggeTegner.DrawPanel;
import context.*;
import model2D.Model2D;
import object3D.MassivTrapp;
import object3D.Block;

import geometry2D.MetricPoint2D;
import geometry2D.Projection2D;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.GeneralPath;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

import org.json.JSONException;
import org.json.JSONObject;

import util.FillStyle;
import util.StrokeStyle;
import util.Util;
import util.Util2;

//***************************************************************************
//*** CLASS: MassivTrappProjection
//***************************************************************************
public class MassivTrappProjection extends BlockProjection implements Context.Constants
{ //private static final boolean DEBUG=true; // Overriding Context.Constants.DEBUG
  static final String TAG="object2D.MassivTrappProjection";
  static final String TYPE="MassivTrapp";

  protected MassivTrapp getMassivTrapp() { return((MassivTrapp)block); }
	
  // *************************************************************************
  // *** CONSTRUCTOR: VeggProjection
  // *************************************************************************
  public MassivTrappProjection(Model2D objectModel,MassivTrapp trapp,int type,int direction,Color color,float opacity)
  throws JSONException
  { super(objectModel,trapp,type,direction,color,opacity); }
  
  public MassivTrappProjection(Model2D objectModel,JSONObject jsonObject) throws JSONException
  { super(objectModel,jsonObject);
    if(DEBUG) Log.d(TAG,"decodeSVG: jsonObject="+jsonObject);
    this.fill=new FillStyle(jsonObject);
    this.stroke=new StrokeStyle(jsonObject);
//    boolean closed=jsonObject.optBoolean("closed",false);
//    JSONArray d=jsonObject.getJSONArray("d");
//    //if(DEBUG) Log.d(TAG,"PathObject.decodeSVG: name="+name+", d="+d);
//    clearPointSet();
//    for(int i=0;i<d.length();i++)
//    { JSONArray p=d.getJSONArray(i);
//      add(new MetricPoint2D(p));
//    }
//    setClosedPath(closed);
  }

  public JSONObject toJSONObject() throws JSONException
  { JSONObject jsonObject=new JSONObject();
    jsonObject.put("type",TYPE);
    jsonObject.put("id",getIdent());
//    jsonObject.put("closed",getClosedPath());  
//    jsonObject.put("d",getD());
    jsonObject.put("fill",fill.encode());
    jsonObject.put("stroke",stroke.encode());
	return(jsonObject);
  }


  // *************************************************************************
  // *** METHOD: paint
  // *************************************************************************
  public void paint(Graphics2D g,DrawPanel drawPanel)
  { Projection2D r=getMassivTrapp().toProjection2D(direction);
    switch(direction)
    { case NORTH: case SOUTH: case EAST: case WEST:
        tegnTrapp(direction,g,r,color); break;
//      case ABOVE: drawProjectionAbove(g,r,color); break;
//      case BELOW: drawProjectionBelow(g,r,color); break;
//      case VCUT: drawVerticalCut(g,r,color); break;
      case ABOVE:
        tegnTrappPlan(g,r,color);
//        tegnTrapp(direction,g,r,color);
        break;
      default: super.paint(g,drawPanel);
    }  
  }

  private void tegnTrapp(int direction,Graphics2D g,Projection2D r,Color c)
  { for(int i=4;i>=0;i--)
    { tegnTrinn(getMassivTrapp().trinnOpp[i],direction,g,murFarge);
      tegnTrinn(getMassivTrapp().trinn[i],direction,g,murFarge);
    }
  }
  
  private void tegnTrinn(Block trinn,int direction,Graphics2D g,Color c)
  { if(trinn!=null)
    { Projection2D r=trinn.toProjection2D(direction);
	  Util.fill(g,r,c,opacity);
	  Util.draw(g,r,opacity);
    }
  }

  private void tegnTrappPlan(Graphics2D g,Projection2D r,Color c)
  {
    tegnTrapp(ABOVE,g,r,c);
    // Tegn PIL !!!!
    float x0=(float)r.getX();
    float y0=(float)(r.getY()+r.getHeight()/2);
    float xT=(float)(r.getX()+(MassivTrapp.innTrinn*3));
    float yT=(float)(r.getY()+r.getHeight()/2);
    float dx=(float)(0.20);
    float dy=(float)(0.15);
    GeneralPath path=new GeneralPath();
    switch(getMassivTrapp().kind)
    {
      case NORTH:
        x0=(float)(r.getX()+r.getHeight()/2);
        y0=(float)(r.getY()+r.getWidth());
        xT=(float)(r.getX()+r.getHeight()/2);
        yT=(float)(r.getY());
        dx=(float)(0.15);
        dy=(float)(0.20);
        path.moveTo(x0,y0);
        path.lineTo(xT,yT);
        path.lineTo(xT+dx,yT+dy);
        path.moveTo(xT-dx,yT+dy);
        path.lineTo(xT,yT);
      break;
      case SOUTH:
        x0=(float)(r.getX()+r.getHeight()/2);
        y0=(float)(r.getY());
        xT=(float)(r.getX()+r.getHeight()/2);
        yT=(float)(r.getY()+r.getWidth());
        dx=(float)(0.15);
        dy=(float)(0.20);
        path.moveTo(x0,y0);
        path.lineTo(xT,yT);
        path.lineTo(xT+dx,yT-dy);
        path.moveTo(xT-dx,yT-dy);
        path.lineTo(xT,yT);
        break;
      case EAST:
        x0=(float)r.getX();
        y0=(float)(r.getY()+r.getHeight()/2);
        xT=(float)(r.getX()+r.getWidth());
        yT=(float)(r.getY()+r.getHeight()/2);
        dx=(float)(0.20);
        dy=(float)(0.15);
        path.moveTo(x0,y0);
        path.lineTo(xT,yT);
        path.lineTo(xT-dx,yT+dy);
        path.moveTo(xT-dx,yT-dy);
        path.lineTo(xT,yT);
        break;
      case WEST:
        x0=(float)(r.getX()+r.getWidth());
        y0=(float)(r.getY()+r.getHeight()/2);
        xT=(float)r.getX();
        yT=(float)(r.getY()+r.getHeight()/2);
        dx=(float)(0.20);
        dy=(float)(0.15);
        path.moveTo(x0,y0);
        path.lineTo(xT,yT);
        path.lineTo(xT+dx,yT+dy);
        path.moveTo(xT+dx,yT-dy);
        path.lineTo(xT,yT);
        break;
    }
    Util.draw(g,path,opacity);
    
  }
  
  // ****************************************************************
  // *** INNER CLASS: EditGeneralPanel
  // ****************************************************************
  public JPanel getEditGeneralPanel(String title)
  { return(new EditGeneralPanel(title)); }
  private class EditGeneralPanel extends JPanel
  { static final long serialVersionUID=0; // AD'HOC
    private JTextField identField;
    private JButton strokeButton;
    private JButton fillButton;
      
    public void paint(Graphics g)
    { if(DEBUG) Log.d(TAG,"EditGeneralPanel.paint: ");
      identField.setText(getIdent());
      strokeButton.setBackground(stroke.getColor());
      fillButton.setBackground(fill.getColor());
  	  super.paint(g);  
    }
    	
    public EditGeneralPanel(String title)
    { setBorder(Util2.getTitleBorder(title));
      if(numberOfPoints()==4) // Firkant
      { setPreferredSize(new Dimension(350,120));//140));
        setLayout(new GridLayout(6,2));
      }
      else
      { setPreferredSize(new Dimension(350,120));
        setLayout(new GridLayout(5,2));
      }
      add(new JLabel("       Ident:"));
      identField=new JTextField(getIdent());
      identField.addActionListener(new ActionListener()
      { public void actionPerformed(ActionEvent e)
        { setIdent(identField.getText()); }
      });
      add(identField);
      fillButton=addEditFillButton(this,true);
      strokeButton=addEditStrokeButton(this,true);
        
      JCheckBox closedBox=new JCheckBox("Closed Path",null,getClosedPath());
      closedBox.addActionListener(new ActionListener()
      { public void actionPerformed(ActionEvent e)
        { setClosedPath(!getClosedPath());
          ByggeTegner.repaint();        	
        }
      });
      add(closedBox);
      add(new JLabel(" ")); // Space only
      
      if(numberOfPoints()==4)
      { JButton parallelogramButton=new JButton("Adjust Parallelogram");
//      parallelogramButton.setBackground(fill.getColor());
        parallelogramButton.addActionListener(new ActionListener()
        { public void actionPerformed(ActionEvent e) { ensureParallelogram(); } });
        add(parallelogramButton);
        
        JButton rectangleButton=new JButton("Adjust Rectangle");
//      rectangleButton.setBackground(fill.getColor());
        rectangleButton.addActionListener(new ActionListener()
        { public void actionPerformed(ActionEvent e) { ensureRectangle(); } });
        add(rectangleButton);
      }
    }
  }
  
  private void ensureParallelogram()
  { if(this.numberOfPoints()==4)
    { MetricPoint2D p0=getMapLocation(0);
      MetricPoint2D p1=getMapLocation(1);
      MetricPoint2D p2=getMapLocation(2);
      MetricPoint2D p3=getMapLocation(3);
      double dx=p1.getX()-p0.getX();
      double dy=p1.getY()-p0.getY();
      p3.setX(p2.getX()-dx);
      p3.setY(p2.getY()-dy);
    }
  }
  
  private void ensureRectangle()
  { if(numberOfPoints()==4)
    { MetricPoint2D p0=getMapLocation(0);
      MetricPoint2D p1=getMapLocation(1);
      MetricPoint2D p2=getMapLocation(2);
      double dx=p1.getX()-p0.getX();
      double dy=p1.getY()-p0.getY();
      double a=p2.getY()-p1.getY();      
      double b=dy/dx*a;
      p2.setX(p1.getX()-b);
      ensureParallelogram();
    }
  }

}